package com.cd.javacxy.module.web.service.impl;

import com.cd.javacxy.common.model.entity.CxyComment;
import com.cd.javacxy.common.model.enums.*;
import com.cd.javacxy.common.model.query.*;
import com.cd.javacxy.common.utils.CxyUtils;
import com.cd.javacxy.common.utils.Page;
import com.cd.javacxy.common.utils.PageResult;
import com.cd.javacxy.exception.BussinessException;
import com.cd.javacxy.module.web.dao.*;
import com.cd.javacxy.module.web.service.CxyCommentService;
import com.cd.javacxy.module.web.service.CxyMessageService;
import com.cd.javacxy.module.web.service.CxyUserService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.HtmlUtils;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * CxyComment的服务接口的实现类
 *
 * @author yanghy
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CxyCommentServiceImpl implements CxyCommentService {

    private final CxyCommentDao commentDao;

    private final FormateAtService formateAtService;

    private final CxyTopicDao cxyTopicDao;

    private final CxyKnowledgeDao cxyKnowledgeDao;

    private final CxyAskDao cxyAskDao;
    private final CxyBlogDao cxyBlogDao;

    private final CxyUserService cxyUserService;
    private final CxyMessageService messageService;

    @Override
    public PageResult<CxyComment> findCommentByPage(CommentQuery commentQuery) {
        commentQuery.setPid(0);
        int pageNum = commentQuery.getPageNum();
        int pageSize = PageSize.PAGE_SIZE10.getSize();
        int count = commentDao.selectCount(commentQuery);
        Page page = new Page(pageNum, count, pageSize);
        commentQuery.setPage(page);
        List<CxyComment> list = this.commentDao.selectList(commentQuery);
        return new PageResult<>(page, list);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public CxyComment getCommentById(Integer commentId) {
        CommentQuery commentQuery = new CommentQuery();
        commentQuery.setCommentId(commentId);
        List<CxyComment> list = this.commentDao.selectList(commentQuery);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addComment(CxyComment comment) throws BussinessException {
        String content = comment.getContent();
        content = CxyUtils.replaceLast(content.replaceFirst("<p>", ""), "</p>", "");
        if (StringUtils.isEmpty(content) || content.length() > TextLengthEnum.LONGTEXT.getLength()
                || comment.getArticleId() == null || comment.getArticleType() == null) {
            throw new BussinessException("参数错误");
        }
        Integer pid = comment.getPid();
        pid = pid == null ? 0 : pid;
        if (pid != 0) {
            //给网页加链接
            content = CxyUtils.addLink(content);
            content = HtmlUtils.htmlEscape(content);
        }
        if (pid != 0 && content.length() > TextLengthEnum.TEXT_500_LENGTH.getLength()) {
            throw new BussinessException("参数错误");
        }

        Set<Integer> userIds = new HashSet<Integer>();
        String formatContent = this.formateAtService.generateRefererLinks(content, userIds);
        //TODO给用户发消息
        comment.setContent(formatContent);
        comment.setCreateTime(LocalDateTime.now());
        this.commentDao.insert(comment);
        UpdateQuery4ArticleCount updateQuery4ArticleCount = new UpdateQuery4ArticleCount();
        updateQuery4ArticleCount.setAddCommentCount(Boolean.TRUE);
        updateQuery4ArticleCount.setArticleId(comment.getArticleId());
        Integer articleUserId;
        if (comment.getArticleType() == ArticleType.TOPIC) {
            this.cxyTopicDao.updateInfoCount(updateQuery4ArticleCount);
            TopicQuery topicQuery = new TopicQuery();
            topicQuery.setTopicId(comment.getArticleId());
            articleUserId = this.cxyTopicDao.selectList(topicQuery).get(0).getUserId();
        } else if (comment.getArticleType() == ArticleType.KNOWLEDGE) {
            this.cxyKnowledgeDao.updateInfoCount(updateQuery4ArticleCount);
            KnowledgeQuery knowledgeQuery = new KnowledgeQuery();
            knowledgeQuery.setTopicId(comment.getArticleId());
            articleUserId = this.cxyKnowledgeDao.selectList(knowledgeQuery).get(0).getUserId();
        } else if (comment.getArticleType() == ArticleType.Ask) {
            this.cxyAskDao.updateInfoCount(updateQuery4ArticleCount);
            AskQuery askQuery = new AskQuery();
            askQuery.setAskId(comment.getArticleId());
            articleUserId = this.cxyAskDao.selectList(askQuery).get(0).getUserId();
        } else if (comment.getArticleType() == ArticleType.BLOG) {
            this.cxyBlogDao.updateInfoCount(updateQuery4ArticleCount);
            BlogQuery blogQuery = new BlogQuery();
            blogQuery.setBlogId(comment.getArticleId());
            articleUserId = this.cxyBlogDao.selectList(blogQuery).get(0).getUserId();
        } else {
            throw new BussinessException("参数错误");
        }
        this.cxyUserService.changeMark(comment.getUserId(), MarkEnum.MARK_COMMENT.getMark());
        if (pid == 0) {
            userIds.add(articleUserId);
        } else {
            CxyComment comment2 = this.getCommentById(pid);
            userIds.add(comment2.getUserId());
        }
        MessageParams messageParams = new MessageParams();
        messageParams.setArticleId(comment.getArticleId());
        messageParams.setArticleType(comment.getArticleType());
        messageParams.setArticleUserId(articleUserId);
        messageParams.setMessageType(MessageType.COMMENT_MESSAGE);
        messageParams.setSendUserName(comment.getUserName());
        messageParams.setSendUserId(comment.getUserId());
        messageParams.setReceiveUserIds(userIds);
        messageParams.setCommentId(comment.getId());
        messageParams.setPageNum(comment.getPageNum());
        messageService.createMessage(messageParams);
        return 0;
    }
}